package app.sceledroid.services;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.concurrent.ExecutionException;

import org.apache.http.cookie.Cookie;
import org.apache.http.impl.client.DefaultHttpClient;
import org.jsoup.nodes.Document;

import android.app.ProgressDialog;
import android.app.Service;
import android.content.Context;
import android.content.Intent;
import android.content.SharedPreferences;
import android.os.Binder;
import android.os.IBinder;
import android.preference.PreferenceManager;
import android.util.Log;
import android.widget.Toast;
import app.sceledroid.R;
import app.sceledroid.activity.LoginActivity;
import app.sceledroid.entity.Course;
import app.sceledroid.entity.Deadline;
import app.sceledroid.entity.Forum;
import app.sceledroid.entity.Resource;
import app.sceledroid.entity.User;
import app.sceledroid.entity.forum.Discussion;
import app.sceledroid.exception.CookieFetcherException;
import app.sceledroid.network.Authenticator;
import app.sceledroid.network.CookieFetcher;
import app.sceledroid.network.CourseItemsGrabber;
import app.sceledroid.network.DeadlineGrabber;
import app.sceledroid.network.DiscussionGrabber;
import app.sceledroid.network.DownloadHandler;
import app.sceledroid.network.ForumGrabber;
import app.sceledroid.network.ResourceGrabber;
import app.sceledroid.network.Uploader;
public class SceleService extends Service {

	private final IBinder sceleBinder = new SceleBinder();
	private DefaultHttpClient client;
	private ArrayList<User> userList = new ArrayList<User>();
	private ArrayList<Course> courses = new ArrayList<Course>();
	private ArrayList<Forum> forums = new ArrayList<Forum>();
	private boolean isCookieAlreadyFetched = false;
	private boolean isAlreadyLogin;

	public class SceleBinder extends Binder {

		public SceleService getService() {
			return SceleService.this;
		}
	}

	@Override
	public IBinder onBind(Intent arg0) {
		// TODO Auto-generated method stub
		Log.v("SceleService", "CLIENT BINDED");

		return sceleBinder;
	}

	@Override
	public void onCreate() {
		// TODO Auto-generated method stub
		super.onCreate();
		client = new DefaultHttpClient();

		Log.v("SceleService", "SCELE SERVICE CREATED");
		SharedPreferences pref = PreferenceManager.getDefaultSharedPreferences(this);
		String username="";
		String passwd = "";
		pref.getString("Username", username);
		pref.getString("Password", passwd);
		if(username != null && passwd != null)
		{
			Log.v("Session", "Created " + username + " : " + passwd);
			
		}
	}

	@Override
	public void onDestroy() {
		// TODO Auto-generated method stub
		super.onDestroy();
		Log.v("SceleService", "SCELE SERVICE DESTROYED");

	}

	@Override
	public int onStartCommand(Intent intent, int flags, int startId) {
		// TODO Auto-generated method stub

		Log.v("SceleService", "SCELE SERVICE STARTED");
		return START_STICKY;
	}

	public void testMethod(Context context) {
		Toast.makeText(context, "TEST METHOD INVOKED", Toast.LENGTH_LONG)
				.show();
	}

	public void authenticateAs(Context context, String username,
			String password, LoginActivity.LoginStatus stat, ProgressDialog dialog) {
		
		if (!isAuthed()) {
			List<Cookie> cStore = client.getCookieStore().getCookies();

			for (Cookie c : cStore) {
				Log.v("Cookie", c.getName() + c.getValue());
			}
			
			Authenticator authenticator = new Authenticator(this, new User(
					username, password, ""), context, client, stat, dialog);
			authenticator.execute(context.getText(R.string.LOGIN_URL)
					.toString());
			
			
		}
	}

	public void fetchCourseItem(Context context, Course course) {
		try {
			CourseItemsGrabber grabber = new CourseItemsGrabber(context,
					client, this);
			grabber.execute(course);

			Document doc = grabber.get();
			fetchDeadline(course, context, doc);
			fetchForum(course, context, doc);
			fetchResource(course, context, doc);

		} catch (InterruptedException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (ExecutionException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}

	public void fetchDeadline(Course course, Context context, Document doc) {

		try {
			DeadlineGrabber deadlineGrabber = new DeadlineGrabber(course,
					context, client);
			deadlineGrabber.execute(doc);

			deadlineGrabber.get();

			ArrayList<Deadline> deadline = course.getDeadlines();
			for (Deadline d : deadline) {
				Log.v("Deadline in SceleService : ", d.getName() + d.getInfo());
			}
			//can;t do it in emulator
			//syncCalendar();
		} catch (InterruptedException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (ExecutionException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}

	public void fetchForum(Course course, Context context, Document doc) {
		try {
			ForumGrabber forumGrabber = new ForumGrabber(course, context,
					client);
			forumGrabber.execute(doc);

			forumGrabber.get();

			ArrayList<Forum> forum = course.getForums();
			forums = forum;
			for (Forum d : forum) {
				Log.v("Forum in SceleService : ", d.getName() + d.getUrl());
			}

		} catch (InterruptedException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (ExecutionException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}

	public void fetchResource(Course course, Context context, Document doc) {
		try {
			ResourceGrabber resourceGrabber = new ResourceGrabber(course,
					context, client);
			resourceGrabber.execute(doc);

			resourceGrabber.get();

			ArrayList<Resource> resource = course.getResources();
			for (Resource d : resource) {
				Log.v("Resource in SceleService : ", d.getName() + d.getUrl());
			}

		} catch (InterruptedException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (ExecutionException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}

	public void fetchDiscussion(Context context, Forum forum) {
		try {
			DiscussionGrabber grabber = new DiscussionGrabber(context, client,
					this);
			grabber.execute(forum);

			grabber.get();
			
		} catch (InterruptedException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (ExecutionException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}

	public void getDefaultCookies(Context context)
			throws CookieFetcherException {
		CookieFetcher fetcher = new CookieFetcher(context, client);
		fetcher.execute();
		try {
			String result = fetcher.get();
			if (result != null) {
				throw new CookieFetcherException();
			} else {
				isCookieAlreadyFetched = true;
				Toast.makeText(context, "Fetching Success", Toast.LENGTH_LONG)
						.show();
			}

		} catch (InterruptedException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (ExecutionException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}

	public boolean isCookieAlreadyInJar() {
		return this.isCookieAlreadyFetched;
	}

	public void addCourse(Course c) {
		courses.add(c);
	}

	public ArrayList<User> getUserList() {
		return this.userList;
	}

	public void addUser(Context context, User user) {
		userList.add(user);
		Toast.makeText(context, "ADDING USER " + user.getUsername(),
				Toast.LENGTH_LONG).show();
	}

	public void deleteUser(Context context, int id) {
		userList.remove(id);
		Toast.makeText(context, "REMOVING USER WITH ID : " + id,
				Toast.LENGTH_LONG).show();
	}

	public ArrayList<Course> getCourses() {
		return this.courses;
	}

	public ArrayList<Deadline> getDeadline(String courseName) {
		Iterator<Course> iterator = courses.iterator();
		Log.v("Course Size ", "Size" + courses.size());
		while (iterator.hasNext()) {
			Course c = iterator.next();
			Log.v("Course", c.getName());
			if (c.getName().equals(courseName)) {
				
				return c.getDeadlines();
			}
		}

		return null;
	}

	public ArrayList<Resource> getResource(String courseName) {
		Iterator<Course> iterator = courses.iterator();
		Log.v("Course Size ", "Size" + courses.size());
		while (iterator.hasNext()) {
			Course c = iterator.next();
			Log.v("Course", c.getName());
			if (c.getName().equals(courseName)) {

				return c.getResources();
			}
		}

		return null;

	}

	public ArrayList<Forum> getForum(String courseName) {
		Iterator<Course> iterator = courses.iterator();
		Log.v("Course Size ", "Size" + courses.size());

		while (iterator.hasNext()) {
			Course c = iterator.next();
			if (c == null) {
				Log.v("C ", "NULL");
			}

			if (c.getName() == null) {
				Log.v("C.getName ", "NULL");
			}

			if (c.getName().equals(courseName)) {
				ArrayList<Forum> forums = c.getForums();
				for (Forum f : forums) {

					Log.v("Forum", f.getName());
				}
				return c.getForums();
			}
		}

		return null;

	}

	public boolean isAuthed() {
		return isAlreadyLogin;
	}


	public ArrayList<Discussion> getDiscussion(String forumName) {
		
		Iterator<Forum> iterator = forums.iterator();
		Log.v("Course Size ", "Size" + forums.size());
		Forum forum = null;
		while(iterator.hasNext())
		{
			Forum f = iterator.next();
			if(f.getName().equalsIgnoreCase(forumName))
				forum = f;
		}
		
		if(forum!=null)
		{
			ArrayList<Discussion> discussions = forum.getDiscussions();
			if(discussions!=null)
			{
				for(Discussion d : discussions)
				{
					if(d!=null)
						Log.v("Discussion", d.getTopic());
				}
				return discussions;
			}
		}
		
		
		return null;
	}
	public boolean downloadFile(Context con, Resource res)
	{
		boolean downloaded = false;
		DownloadHandler download = new DownloadHandler( client, res.getName());
		download.execute(res);
		try {
			if( download.get().booleanValue())
				downloaded = true;
		} catch (InterruptedException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (ExecutionException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		
		return downloaded;
	}
	
	public boolean uploadFile(Context con, Deadline d, String filename)
	{
		boolean uploaded = false;
		Uploader upload = new Uploader(client,filename);
		upload.execute(d);
		try {
			if(upload.get().booleanValue())
				uploaded=true;
		} catch (InterruptedException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (ExecutionException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		return uploaded;
	}
	
	public void setLogin(boolean isLogin)
	{
		this.isAlreadyLogin = isLogin;
	}
	
	

	public void syncCalendar() {
		for (Course c : courses) {
			List<Deadline> deadlines = c.getDeadlines();
			if (deadlines != null) {
				for (Deadline d : deadlines) {

					Intent intent = new Intent(Intent.ACTION_EDIT);

					intent.addCategory(Intent.CATEGORY_DEFAULT);
					intent.setType("vnd.android.cursor.item/event");
					intent.putExtra(Event.EVENT_BEGIN_TIME, d.getDateStart()
							.getTime());

					intent.putExtra(Event.EVENT_END_TIME, d.getDateStart()
							.getTime());
					intent.putExtra(Event.EVENT_TITLE, d.getName());
					intent.putExtra(Event.EVENT_DESCRIPTION, d.getInfo());
					intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
					startActivity(intent);

				}

			}
		}
	}

}
